#include "mot823111.h"

/* Распиновка платы
 *
 * M1       dir     port    pin
 * M1.A     out     B       15
 * M1.B     out     B       14
 * M1.EN    out     A       11
 * M1.DIAG  in      A       8
 * M1.PWM   out_p   B       8
 * M1.CS    ain     adc1    5(PA5)              0
 *
 * M2       dir     port    pin
 * M2.A     out     B       13
 * M2.B     out     B       12
 * M2.EN    out     B       10
 * M2.DIAG  in      B       11
 * M2.PWM   out_p   B       9
 * M2.CS    ain     adc1    0(PA0)              1
 *
 * LEDA     out     C       13
 * LEDB     out     C       14
 *
 * SIG1     ain     adc1    7(PA7)  //left      2
 * SIG2     ain     adc1    9(B1)   //right     3
 *
 * SetP     out_p   B       6
 * SetP     out_p   A       4       DAC1_OUT
 *
 * VS       ain     adc1    8(PB0)              4
 * TEMP     ain     adc1    6(PA6)              5
 *
 * ENDA     in      A       13
 * ENDB     in      A       12
 *
 * Vref                                         6
 * Termometr                                    7
 * */

//Global variables

/*
 * Буфер для результатов измерения АЦП
 * Значения постоянно обновляются через DMA
 */
volatile uint16_t AnalogInputs[8];


// ----------------------------------------------------------------------------
void SetPeriphClock(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM17, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

}


// ----------------------------------------------------------------------------
void M1_Init (void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    // out
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // out
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // in
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // adc
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // port B.8 mast be set to PWM
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // Timer 16 init as PWM
    TIM_DeInit(TIM16);

    TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
    TIM_TimeBaseStructInit(&TIM_BaseInitStructure);

    TIM_BaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_BaseInitStructure.TIM_Period = 1024;
    TIM_BaseInitStructure.TIM_Prescaler = 2;	// на 8 МГц 0 = 35 кГц, 1 = 17, 2 = < 10
    TIM_TimeBaseInit(TIM16, &TIM_BaseInitStructure);

    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit(&TIM_OCInitStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // TIM_OCMode_PWM1
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // High
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
    TIM_OCInitStructure.TIM_Pulse = 0;      // начальное значение = выключено
    TIM_OC1Init(TIM16, &TIM_OCInitStructure);

    TIM_BDTRInitTypeDef TIM_BDTRStructure;
    TIM_BDTRStructInit(&TIM_BDTRStructure);

    TIM_BDTRStructInit(&TIM_BDTRStructure);
    TIM_BDTRStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
    TIM_BDTRConfig(TIM16, &TIM_BDTRStructure);

    TIM_OC1PreloadConfig(TIM16, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM16, ENABLE);

    TIM_Cmd(TIM16, ENABLE);
}
// ----------------------------------------------------------------------------
void M2_Init (void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    // out
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_12 | GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // in
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // adc
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // port B.9 mast be set to PWM
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // Timer 17 init as PWM
    TIM_DeInit(TIM17);

    TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
    TIM_TimeBaseStructInit(&TIM_BaseInitStructure);

    TIM_BaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_BaseInitStructure.TIM_Period = 1024;
    TIM_BaseInitStructure.TIM_Prescaler = 2;	// на 8 МГц 0 = 35 кГц, 1 = 17, 2 = < 10
    TIM_TimeBaseInit(TIM17, &TIM_BaseInitStructure);

    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit(&TIM_OCInitStructure);

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // TIM_OCMode_PWM1
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // High
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
    TIM_OCInitStructure.TIM_Pulse = 0;      // начальное значение = выключено
    TIM_OC1Init(TIM17, &TIM_OCInitStructure);

    TIM_BDTRInitTypeDef TIM_BDTRStructure;
    TIM_BDTRStructInit(&TIM_BDTRStructure);

    TIM_BDTRStructInit(&TIM_BDTRStructure);
    TIM_BDTRStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
    TIM_BDTRConfig(TIM17, &TIM_BDTRStructure);

    TIM_OC1PreloadConfig(TIM17, TIM_OCPreload_Enable);
    TIM_ARRPreloadConfig(TIM17, ENABLE);

    TIM_Cmd(TIM17, ENABLE);
}
// ----------------------------------------------------------------------------
void M1_Set(M_CmdTypeDef cmd, uint16_t Speed)    // direction (Left, Right, Stop), Speed 0-100%
{
    // Enable driver
    GPIOA->ODR |= GPIO_Pin_11;

    switch (cmd)
    {
        case M_Left:                             // left
            // Set A to Lo B15
            GPIOB->ODR &= ~GPIO_Pin_15;
            // Set B to Hi  B14
            GPIOB->ODR |= GPIO_Pin_14;
            // Set Speed B 8
            TIM16->CCR1 = Speed;
            break;

        case M_Right:                             // right
            // Set A to Hi B15
            GPIOB->ODR |= GPIO_Pin_15;
            // Set B to Lo  B14
            GPIOB->ODR &= ~GPIO_Pin_14;
            // Set Speed B 8
            TIM16->CCR1 = Speed;
            break;

        case M_Stop:                             // stop
            // Set A to Lo B15
            GPIOB->ODR &= ~GPIO_Pin_15;
            // Set B to Lo  B14
            GPIOB->ODR &= ~GPIO_Pin_14;
            // Set Speed B 8
            TIM16->CCR1 = 0;        				// break speed
            break;

        case M_Free:                             // free
            // free enable pin
            GPIOA->ODR &= ~GPIO_Pin_11;				// driver off
            // Set Speed B 8
            TIM16->CCR1 = 0;
            // Set A to Lo B15
            GPIOB->ODR &= ~GPIO_Pin_15;
            // Set B to Lo  B14
            GPIOB->ODR &= ~GPIO_Pin_14;
            break;

        default:
            break;
    }
}

// ----------------------------------------------------------------------------
void M2_Set(M_CmdTypeDef cmd, uint16_t Speed)    // direction (Left, Right, Stop), Speed 0-100%
{
    // Enable driver
    GPIOB->ODR |= GPIO_Pin_10;

    switch (cmd)
    {
        case M_Left: //left
            // Set A to Lo B13
            GPIOB->ODR &= ~GPIO_Pin_13;
            // Set B to Hi  B12
            GPIOB->ODR |= GPIO_Pin_12;
            // Set Speed B 9
            TIM17->CCR1 = Speed;
            break;

        case M_Right: // right
            // Set A to Hi B13
            GPIOB->ODR |= GPIO_Pin_13;
            // Set B to Lo  B12
            GPIOB->ODR &= ~GPIO_Pin_12;
            // Set Speed B 9
            TIM17->CCR1 = Speed;
            break;

        case M_Stop: //stop
            // Set A to Lo B13
            GPIOB->ODR &= ~GPIO_Pin_13;
            // Set B to Lo  B12
            GPIOB->ODR &= ~GPIO_Pin_12;
            // Set Speed B 9
            TIM17->CCR1 = 0;
            break;

        case M_Free: // free
            // free enable pin B 10
            GPIOB->ODR &= ~GPIO_Pin_10;
            // Set A to Lo B13
            GPIOB->ODR &= ~GPIO_Pin_13;
            // Set B to Lo  B12
            GPIOB->ODR &= ~GPIO_Pin_12;
            // Set Speed B 9
            TIM17->CCR1 = 0;
            break;

        default:
            break;
    }
}

// ----------------------------------------------------------------------------
void MAdc_Init(void)            // settingsup the ADC to single conversion
{
    // эта штука не используется, но рас написана, то пусть останется

	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    ADC_DeInit(ADC1);

    ADC_InitTypeDef ADC_InitStructure;

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1; // for single conv mode set 1

    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_Cmd(ADC1, ENABLE);

    ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1)) { };
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1)) { };

    #ifdef  VECT_TAB_RAM
        /* Set the Vector Table base location at 0x20000000 */
        NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
    #else  /* VECT_TAB_FLASH  */
        /* Set the Vector Table base location at 0x08000000 */
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    #endif

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = ADC1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);


}


// ----------------------------------------------------------------------------
void MAdc_InitDMA(void)            // settingsup the ADC to single conversion [for test]
{
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);                               // set clock source
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    ADC_DeInit(ADC1);                                               // ADC reset
    ADC_InitTypeDef ADC_InitStructure;                              // settings parameter structure

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;                    	// Scan mode
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;              	// Continuous mode
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // no external trigger
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;          	// data align
    ADC_InitStructure.ADC_NbrOfChannel = 8;                         	// for single conv mode set 1

    ADC_Init(ADC1, &ADC_InitStructure);                             // ADC Init

    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_71Cycles5);  	// M1 current sense	 = M_ADC_M1CS
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_71Cycles5);  	// M2 current sense	 = M_ADC_M2CS
    ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 3, ADC_SampleTime_71Cycles5);  	// SIG1				 = M_ADC_SIGA
    ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 4, ADC_SampleTime_71Cycles5);  	// SIG2				 = M_ADC_SIGB
    ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 5, ADC_SampleTime_71Cycles5);  	// VS				 = M_ADC_VS
    ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 6, ADC_SampleTime_71Cycles5);  	// TEMP				 = M_ADC_BoardTemp
    ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 7, ADC_SampleTime_239Cycles5);  	// TEMP				 = M_ADC_VRef
    ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 8, ADC_SampleTime_239Cycles5);  	// TEMP				 = M_ADC_ChipTerm

    DMA_DeInit(DMA1_Channel1);                                      // DMA DeInit

    DMA_InitTypeDef DMA_InitStructure;                              // DMA settings parametr structure

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);//ADC1_BASE+0x4c;  //ADC1_BASE+0x4c
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //siseof(AnalogInputs);

    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AnalogInputs;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 8;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

    DMA_Init(DMA1_Channel1, &DMA_InitStructure);                // DMA Init

    // Enable DMA1 channel1
    DMA_Cmd(DMA1_Channel1, ENABLE);

    // Enable ADC1 DMA
    ADC_DMACmd(ADC1, ENABLE);

    ADC_Cmd(ADC1, ENABLE);										// ADC1 On

    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1))
    { };
    ADC_StartCalibration(ADC1);
    while(ADC_GetCalibrationStatus(ADC1))
    { };

    ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

// ----------------------------------------------------------------------------
void MAdc_Start(void)          // start conversion
{
    // включение преобразования в одноразовом режиме
	// single channel conversion
    ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_1Cycles5);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}

// ----------------------------------------------------------------------------
void ADC1_IRQHandler(void)	    // Interrupt Handler
{

    // перенести данные после преобразования
	if(ADC_GetITStatus(ADC1, ADC_IT_EOC))
    {
        ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
        //SIG2 = ADC_GetConversionValue(ADC1);
        AnalogInputs[3] = ADC_GetConversionValue(ADC1);
    }
};

// ----------------------------------------------------------------------------
void DMA1_Channel1_IRQHandler(void)
{
	// было сделано не помню для чего
	// но сейчас не используется.
	// сброс флага оставлен на всякий случай

	NVIC_ClearPendingIRQ(DMA1_Channel1_IRQn);
};

// ----------------------------------------------------------------------------
void InitPeriph(void)
{
    // конфигурация портов для светодиодов
	GPIO_InitTypeDef  GPIO_InitStructure0;

    GPIO_InitStructure0.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;
    GPIO_InitStructure0.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure0.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOC, &GPIO_InitStructure0);

    GPIOC->ODR |= GPIO_Pin_13;
    GPIOC->ODR |= GPIO_Pin_14;

    /*
    // ��������� �����
    USART_InitTypeDef USART_InitStructure;
    USART_InitTypeDef USART_ClockInitStruct;
    GPIO_InitTypeDef  GPIO_InitStructure;

    ///USART_ClockInitStruct.

    // Enable GPIOA clock
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA, ENABLE);

    // Configure USART1 Rx (PA10) as input floating
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // Configure USART1 Tx (PA9) as alternate function push-pull
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
*/
    /* USART1 configured as follow:
          - BaudRate = 115200 baud
          - Word Length = 8 Bits
          - One Stop Bit
          - No parity
          - Hardware flow control disabled (RTS and CTS signals)
          - Receive and transmit enabled
          - USART Clock disabled
          - USART CPOL: Clock is active low
          - USART CPHA: Data is captured on the middle
          - USART LastBit: The clock pulse of the last data bit is not output to
                           the SCLK pin
    */
/*
    USART_InitStructure.USART_BaudRate            = 9600;
    USART_InitStructure.USART_WordLength          = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits            = USART_StopBits_1;
    USART_InitStructure.USART_Parity              = USART_Parity_No ;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);

    USART_Cmd(USART1, ENABLE);
*/

}

// ----------------------------------------------------------------------------
void TogleLEDA(void)
{
	GPIOC->ODR ^= GPIO_Pin_13;
}

// ----------------------------------------------------------------------------
void OnLEDA(void)
{
    GPIOC->ODR &= ~GPIO_Pin_13;
}
// ----------------------------------------------------------------------------
void OffLEDA(void)
{
    GPIOC->ODR |= GPIO_Pin_13;
}

// ----------------------------------------------------------------------------
void TogleLEDB(void)
{
	GPIOC->ODR ^= GPIO_Pin_14;
}
// ----------------------------------------------------------------------------
void OnLEDB(void)
{
    GPIOC->ODR &= ~GPIO_Pin_14;
}
// ----------------------------------------------------------------------------
void OffLEDB(void)
{
    GPIOC->ODR |= GPIO_Pin_14;
}

// ----------------------------------------------------------------------------
/*
 * Просто ничего не делание указанное количество циклов
 * */
void Delay(uint32_t nCount)
{
    //
	for (; nCount != 0; nCount--)
	{
		;
	};
}

// ----------------------------------------------------------------------------
void SetupClock()
{

	RCC_DeInit ();                    // RCC system reset(for debug purpose)
    RCC_HSEConfig (RCC_HSE_ON);       // Enable HSE

    // Wait till HSE is ready
    while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);

    RCC_HCLKConfig   (RCC_SYSCLK_Div1);   // HCLK   = SYSCLK
    RCC_PCLK2Config  (RCC_HCLK_Div1);     // PCLK2  = HCLK
    RCC_PCLK1Config  (RCC_HCLK_Div1);     // PCLK1  = HCLK/2
    RCC_ADCCLKConfig (RCC_PCLK2_Div4);    // ADCCLK = PCLK2/4

    // PLLCLK = 8MHz * 9 = 72 MHz
    RCC_PLLConfig (0x00010000, RCC_PLLMul_3);

    RCC_PLLCmd (ENABLE);                  // Enable PLL

    // Wait till PLL is ready
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

    // Select PLL as system clock source
    RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);

    // Wait till PLL is used as system clock source
    while (RCC_GetSYSCLKSource() != 0x08);



}

// ----------------------------------------------------------------------------
void ENDs_Init (void)          // init ENDs GPIO as input with PU
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

// ----------------------------------------------------------------------------
uint8_t ENDA (void)           // End switch A
{
	uint8_t tmp = 0, i = 0;

    for(i = 0; i < 10; i++)
        if((GPIOA->IDR & GPIO_Pin_13) == 0) // active Lo
            tmp ++;

    if(tmp >= 5)
        tmp = 1;
    else
        tmp = 0;
    return tmp;
}

// ----------------------------------------------------------------------------
uint8_t ENDB (void)           // End switch B
{

	uint8_t tmp = 0, i = 0;

    for(i = 0; i < 20; i++)
        if((GPIOA->IDR & GPIO_Pin_12) == 0) // active Lo
        {
        	tmp ++;
        	//Delay(40);
        }

    if(tmp >= 10)
        tmp = 1;
    else
        tmp = 0;
    return tmp;

	/*
	if((GPIOA->IDR & GPIO_Pin_12) == 0)
		return 1;
	else
		return 0;

	*/
}

// ----------------------------------------------------------------------------
uint16_t ReadIntTemp(void)     // read data from ADC and fata to temperature conversion
{
    // read reference manual at page 170 for more details

    //float Vpower = 4900.0f / AnalogInputs[7];
    //float Vsense = (Vpower * AnalogInputs[6]) / 4096.0f;
    uint16_t temp = 0;
    //temp = (1.43f - (((4900.0 / AnalogInputs[7]) * AnalogInputs[6]) / 4096.0)) / 0.0043f + 23.0;

    /*
     * Vpower = 4900.0f / Adс_17;
     * Vsense = (Vpower * Adc_16) / 4096.0f;
     * Temperatura = (1.43f - Vsense) / 0.0043f + 23.0f;
     *
     * */

    temp = 0;
    return temp;
}

// ----------------------------------------------------------------------------

unsigned char tab[8] = {0,63,127,191,255,191,127,63};

// ----------------------------------------------------------------------------
void SetP_Init(void)           // set up the DAC to pressure control
{
    // Init port (pin)
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // Init DAC
    DAC_InitTypeDef DAC_InitStructure;

    DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1; // ни на что не влияет
    DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
    DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
    DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; //DAC_WaveGeneration_None

    DAC_Init(DAC_Channel_1, &DAC_InitStructure);

    DAC_DMACmd(DAC_Channel_1, ENABLE);

    DAC_Cmd(DAC_Channel_1, ENABLE);

    // Init DMA
    DMA_DeInit(DMA1_Channel5);                                      // DMA DeInit

    DMA_InitTypeDef DMA_InitStructure;                              // DMA settings parametr structure

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR8R1;  // этот регистр, значит данные однобайтные
    //DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&tab[0];
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&sndMsg[0];    // play the music
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 4976; // for "tab" = 8
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //siseof(AnalogInputs);
    DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

    DMA_Init(DMA1_Channel5, &DMA_InitStructure);                // DMA Init

    // Enable DMA1 channel1
    DMA_Cmd(DMA1_Channel5, ENABLE);

    // Init timer
    TIM_TimeBaseInitTypeDef TIM_InitStructure;

    TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_InitStructure.TIM_RepetitionCounter = 0;
    TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    //TIM_InitStructure.TIM_Prescaler = 8000-1;   // 1 ms step              for "tab" check
    //TIM_InitStructure.TIM_Period = 5000-1;      // 5000 steps = 5 sec
    TIM_InitStructure.TIM_Prescaler = 8-1;          // 1 us step
    //TIM_InitStructure.TIM_Period = 3628-1;          // 3628 us = 2756.25 Hz = 20050 Hz / 8
    TIM_InitStructure.TIM_Period = 907-1;          // 90 us = 10025 Hz = 20050 Hz / 2
    //TIM_InitStructure.TIM_Period = 1814-1;          // 90 us = 5512 Hz = 20050 Hz / 4


    TIM_TimeBaseInit(TIM15, &TIM_InitStructure);



    //TIM_DMACmd(TIM15,TIM_DMA_Trigger, ENABLE);
    TIM_DMACmd(TIM15,TIM_DMA_Update, ENABLE);
    //TIM15->DIER |= TIM_DIER_UDE;

    TIM_Cmd(TIM15, ENABLE);

    // Start


}
// ----------------------------------------------------------------------------
void PlaySound(void)           // run DMA to play the Sound 1 time
{
    // Enable DMA1 channel1
    //DMA_Cmd(DMA1_Channel5, ENABLE);
    //TIM_Cmd(TIM15, ENABLE);
    TIM15->CR1 ^= 1;

}
// ----------------------------------------------------------------------------
/*
 * Обработка нажатия кнопки
 * */
/*
void BtnAct(uint8_t PrevState, uint8_t NewState, void *OnAct, void *OffAct)
{

	// BTNB logic
    if(PrevState != NewState)
    {
        if(NewState == 1)
        {
        	OnAct;
        }
        else
        {
            // do on Low
        	OffAct;
        }
        PrevState = NewState;
    }

}
*/
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------

